#!/usr/bin/python
#-*-coding:utf-8-*-
 
###############################################################
## Name       : gen_rtl_dummy
## Author     : xiaotu
## Time       : 2021-07-06 11:11:19
## Description:
## 
## 
###############################################################
 
import sys
import os
import re
import argparse
import math
 
signal_list = []
class Signal:
    name_width = 1
    widh_width = 1
    def __init__(self, name, module, type="wire", port="none", width = ""):
        self.name   = name
        self.module = module
        self.type   = type
        self.port   = port
        self.width  = width
        Signal.name_width  = max(Signal.name_width, len(name))
        Signal.widh_width  = max(Signal.widh_width, len(width))
 
    def __str__(self):
        str = "Class Signal\n"
        str = str + "    name   : %s\n" % self.name
        str = str + "    module : %s\n" % self.module
        str = str + "    type   : %s\n" % self.type
        str = str + "    port   : %s\n" % self.port
        str = str + "    width  : %s\n" % self.width
        str = str + "    max name_width = %s\n" % Signal.name_width
        return str

def del_note_code(handle):
    ret_handle = []
    del_flag = 0
    for line in handle:
        re_s  = re.search(r"^\/\*", line)
        re_e  = re.search(r"\*\/", line)
        re_se = re.search(r"^\/\*.*\*\/$", line)
        line  = re.sub(r"\/\/.*$", "", line)
        if re_se:
            continue
        elif re_s:
            del_flag = 1
        elif re_e:
            del_flag = 0
            continue

        if del_flag != 1:
            ret_handle.append(line)

    return ret_handle

def width_space_ex(matched):
    return " " + matched.group(1) + " "

def sys_rtl_file(file):
    with open (file, "r") as rtl:
        handle = rtl.readlines()
        handle = del_note_code(handle)
        module= "none"
        for line in handle:
            line = line.strip()
            line = re.sub("(\[.*\])", width_space_ex, line)
            re0 = re.match(r"module\s+(\w+)", line)
            re1 = re.search(r"^\s*(input|output|wire|reg)(\s+wire|\s+reg)?\s+(\[.*\])?\s*([\s,\w]+)\s*", line)
            type = "wire"
            port = "none"
            width = ""
            if re0:
                module = re0.group(1)
            if re1:
                if re1.group(3):
                    width = re1.group(3)
                if re.match(r"input|output", re1.group(1)):
                    port = re1.group(1).strip()
                else:
                    type = re1.group(1).strip()
                if re1.group(2):
                    type = re1.group(2).strip()
                for sig in re1.group(4).split(r"\s*,\s*"):
                    name = sig.strip(",")
                    s = Signal(name, module, type, port, width)
                    signal_list.append(s)
    for sig in signal_list:
        print(sig)
 
def input_args_proc():
    global rtl_file 
    global module_name
    parser = argparse.ArgumentParser(description="argparse info")
    parser.add_argument('-o', action='store_true', default=False, help='open this script')
    parser.add_argument('-f', help='input rtl.v')
    result = parser.parse_args()
    if result.o == True:
        os.system("gvim %s" % __file__)
        sys.exit(0)
    rtl_file = result.f
    (module_name, extension) = os.path.splitext(rtl_file)
 
def gen_title():
    title_list = []
    user = os.popen('whoami').readline()
    date = os.popen('date "+%Y-%m-%d %H:%M:%S"').readline()
    name = module_name + "_dummy"
 
    title_list.append("//#############################################################")
    title_list.append("// Name       :" + name.strip())
    title_list.append("// Author     :" + user.strip())
    title_list.append("// Time       :" + date.strip())
    title_list.append("// Description:")
    title_list.append("// ")
    title_list.append("// ")
    title_list.append("//#############################################################")
    title_list.append("")
    return title_list
 
def write_list(list, file = ""):
    if file == "":
        for line in list:
            print(line + "\n")
    else:
        with open(file, "w") as handle:
            for line in list:
                handle.write(line + "\n")
 
def gen_dummy():
	global module_name
    dummy_list = gen_title()
    dummy_list.append("module %s(" % module_name)
    dummy_list.append("    //output port")
    input_list  = []
    input_declare_list = []
    output_list = []
    output_declare_list = []
    for sig in signal_list:
        if sig.port == "input":
            input_list.append("    " + sig.name + ",")
            input_declare_list.append("input  " + sig.width.ljust(Signal.widh_width) + " " + sig.name + ";")
        if sig.port == "output":
            output_list.append("    " + sig.name + ",")
            output_declare_list.append("output " + sig.width.ljust(Signal.widh_width) + " " + sig.name + ";")
    input_list[-1] = re.sub(r",", "", input_list[-1])
    dummy_list.extend(output_list)
    dummy_list.append("    //input port")
    dummy_list.extend(input_list)
    dummy_list.append(");")
    dummy_list.append("")
    dummy_list.extend(output_declare_list)
    dummy_list.append("")
    dummy_list.extend(input_declare_list)
    dummy_list.append("")
    dummy_list.append("endmodule")
 
    write_list(dummy_list, module_name + "_dummy.v")
 
def gen_dummy_with_tie0():
	global module_name
    dummy_list = gen_title()
    dummy_list.append("module %s(" % module_name)
    dummy_list.append("    //output port")
    input_list  = []
    input_declare_list = []
    output_list = []
    output_declare_list = []
    output_tie0_list = []
    for sig in signal_list:
        if sig.port == "input":
            input_list.append("    " + sig.name + ",")
            input_declare_list.append("input  " + sig.width.ljust(Signal.widh_width) + " " + sig.name + ";")
        if sig.port == "output":
            output_list.append("    " + sig.name + ",")
            output_declare_list.append("output " + sig.width.ljust(Signal.widh_width) + " " + sig.name + ";")
            tie = "1'b0"
            if sig.width != "":
                part = re.sub(r"\[", "", sig.width)
                part = re.sub(r"\]", "", part)
                (part1, part2) = part.split(":")
                wd1 = part1.strip()
                wd2 = part2.strip()
                wd  = "(%s-%s+1)" % (wd1, wd2)
                tie = "{(%s){1'b0}}" % wd
            output_tie0_list.append("assign " + sig.name.ljust(Signal.name_width) + " = " + tie + ";")
    input_list[-1] = re.sub(r",", "", input_list[-1])
    dummy_list.extend(output_list)
    dummy_list.append("    //input port")
    dummy_list.extend(input_list)
    dummy_list.append(");")
    dummy_list.append("")
    dummy_list.extend(output_declare_list)
    dummy_list.append("")
    dummy_list.extend(input_declare_list)
    dummy_list.append("")
    dummy_list.extend(output_tie0_list)
    dummy_list.append("")
    dummy_list.append("endmodule")    
 
    write_list(dummy_list, module_name + "_dummy.v")
 
 
def main():
    global rtl_file
    print("%s is working" % __file__)
    input_args_proc()
    sys_rtl_file(rtl_file)
    gen_title()
    sel = input('''1.生成dummy文件
2.生成dummy文件，输出信号tie0
选择你要进行的操作：''')
    if sel == 1:
        gen_dummy()
    if sel == 2:
        gen_dummy_with_tie0()
 
if __name__ == "__main__":
    main()
